﻿package {

	public class NanoGroup {

		// Constants:
		// Public Properties:
		// Private Properties
		private var gridX:Number;
		private var gridY:Number;
		private var halted:Boolean;//Set to false if the group has come to rest.
		private var inUse:Boolean;//Intermediary value, set to false if falling path is obstructed
		private var orb1:NanoOrb;
		private var orb2:NanoOrb;
		private var rotState:Number; //Denotes rotation of the pill
		//State 1 = Horizontal o1o2
		//State 2 = Vertical o1o2
		//State 3 = Horizontal o2o1
		//State 4 = Vertical o2o1
		// Initialization:
		public function NanoGroup(orbOne:NanoOrb, orbTwo:NanoOrb):void {
			orb1=orbOne;
			orb2=orbTwo;
			gridX=orb1.getGridX();
			gridY=orb1.getGridY();
			orb1.setPartnerLocal("right");
			orb2.setPartnerLocal("left");
			rotState=1;
			inUse = true;
			halted = false;
		}
		// Public Methods:
		//Getters and Setters
		public function getGridX():Number {
			return gridX;
		}
		public function setGridX(tempX:Number):void {
			gridX=tempX;
		}
		public function getGridY():Number {
			return gridY;
		}
		public function setGridY(tempY:Number):void {
			gridY=tempY;
		}
		public function getInUse():Boolean {
			return inUse;
		}
		public function setInUse(tempUse:Boolean):void {
			inUse=tempUse;
		}

		public function getOrbOne():NanoOrb {
			return orb1;
		}
		public function getOrbTwo():NanoOrb {
			return orb2;
		}
		//END Getters and Setters
		//Checks against the current grid setup to see if the group can shift down
		//If the group can shift down it will.
		public function shiftDown(grid:Grid):void {
			if(checkDownCollision(grid)){
				gridY++;
				orb1.setGridY(orb1.getGridY()+1);
				orb2.setGridY(orb2.getGridY()+1);
			} else if(inUse){
				inUse = false;
			}
		}
		//Shifts the NanoGroup right if it is possible.
		public function shiftRight(grid:Grid):void {
			if(checkRightCollision(grid)){
				gridX++;
				orb1.setGridX(orb1.getGridX()+1);
				orb2.setGridX(orb2.getGridX()+1);
			}
		}
		//Shifts the NanoGroup left if it is possible.
		public function shiftLeft(grid:Grid):void {
			if(checkLeftCollision(grid)){
				gridX--;
				orb1.setGridX(orb1.getGridX()-1);
				orb2.setGridX(orb2.getGridX()-1);
			}
		}
		//Checks adjacent grid spots in order to determine if the group can move left
		public function checkLeftCollision(grid:Grid):Boolean{
			if(rotState == 1 || rotState == 3){
				if(grid.hasOrbThere(gridX-1,gridY) || gridX == 0){
					return false;
				} else {
					return true;
				}
			} else if(rotState == 2 || rotState == 4){
				if(grid.hasOrbThere(gridX-1,gridY) || grid.hasOrbThere(gridX-1,gridY-1) || gridX == 0){
					return false;
				} else {
					return true;
				}
			}
			return false;
		}
		//Checks adjacent grid spots in order to determine if the group can move Right
		public function checkRightCollision(grid:Grid):Boolean{
			if(rotState == 1 || rotState == 3){
				if(grid.hasOrbThere(gridX+2,gridY) || gridX+1 == 7){
					return false;
				} else {
					return true;
				}
			} else if(rotState == 2 || rotState == 4){
				if(grid.hasOrbThere(gridX+1,gridY) || grid.hasOrbThere(gridX+1,gridY-1) || gridX == 7){
					return false;
				} else {
					return true;
				}
			}
			return false;
		}
		//Checks adjacent grid spots in order to determine if the group can move Down
		public function checkDownCollision(grid:Grid):Boolean{
			if(rotState == 1 || rotState == 3){
				if(grid.hasOrbThere(gridX,gridY+1) || grid.hasOrbThere(gridX+1,gridY+1) || gridY == 15){
					return false;
				} else {
					return true;
				}
			} else if(rotState == 2 || rotState == 4){
				if(grid.hasOrbThere(gridX,gridY+1) || gridY == 15){
					return false;
				} else {
					return true;
				}
			}
			return false;
		}
		//Function that rotates the NanoGroup based on the current rotation state
		public function rotate(grid:Grid):void {
			//State 1 = Horizontal o1o2
			//State 2 = Vertical o1o2
			//State 3 = Horizontal o2o1
			//State 4 = Vertical o2o1
			if (rotationCheck(grid)) {
				switch (rotState) {
					case 1 :
						{
							//Rotates into State 2
							orb2.setGridX(orb2.getGridX()-1);
							orb2.setGridY(orb2.getGridY()-1);
							orb1.setPartnerLocal("up");
							orb2.setPartnerLocal("down");
							rotState=2;
							break;

						};
					case 2 :
						{
							//Rotates into State 3
							orb1.setGridX(orb1.getGridX()+1);
							orb2.setGridY(orb2.getGridY()+1);
							orb1.setPartnerLocal("left");
							orb2.setPartnerLocal("right");
							rotState=3;
							break;

						};
					case 3 :
						{
							//Rotates into State 4
							orb1.setGridX(orb1.getGridX()-1);
							orb1.setGridY(orb1.getGridY()-1);
							orb1.setPartnerLocal("down");
							orb2.setPartnerLocal("up");
							rotState=4;
							break;

						};
					case 4 :
						{
							//Rotates back to State 1
							orb1.setGridY(orb1.getGridY()+1);
							orb2.setGridX(orb2.getGridX()+1);
							orb1.setPartnerLocal("right");
							orb2.setPartnerLocal("left");
							rotState=1;
							break;

					}
				}
			}

		};

		// Protected Methods:
		//Checks adjacent orbs to see if the next rotation state can be acheived.
		//Returns true if rotation can be accomplished
		private function rotationCheck(grid:Grid):Boolean {
			//Checks to see if the rotation of the NanoGroup is possible.
			var canRotate:Boolean;
			switch (rotState) {
				case 1 :
					{
						if (orb1.getGridY()==0) {
							canRotate=false;
							break;
						} else if (grid.hasOrbThere((orb2.getGridX()-1),(orb2.getGridY()-1))) {
							canRotate=false;
							break;
						} else {
							canRotate=true;
						}
						break;

					};
				case 2 :
					{
						if (orb1.getGridX()==7) {
							canRotate=false;
							break;
						} else if (grid.hasOrbThere((orb1.getGridX()+1),orb1.getGridY())) {
							canRotate=false;
							break;
						} else {
							canRotate=true;
						}
						break;

					};
				case 3 :
					{
						if (orb1.getGridY()==0) {
							canRotate=false;
							break;
						} else if (grid.hasOrbThere((orb1.getGridX()-1),(orb1.getGridY()-1))) {
							canRotate=false;
							break;
						} else {
							canRotate=true;
						}
						break;

					};
				case 4 :
					{
						if (orb1.getGridX()==7) {
							canRotate=false;
							break;
						} else if (grid.hasOrbThere((orb2.getGridX()+1),(orb2.getGridY()))) {
							canRotate=false;
						} else {
							canRotate=true;
						}
						break;

					};
				default :
					{
						canRotate=false;
						break;

				}
			};
			return canRotate;
		}
	}

}